package com.mapler.neteller.service;

import com.mapler.ngfx.service.*;
import com.mapler.model.AdModel;
import com.mapler.model.SModel;
import com.mapler.model.UAModel;
import com.mapler.service.INotifier;
import com.mapler.service.MailRunner;
import com.mapler.utility.HttpHelper;
import com.mapler.utility.IConstant;
import com.mapler.utility.Util;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

/**
 *
 * @author none
 */
public class NetellerSignupClick implements Runnable {

    private SModel sModel;
    private ArrayList<UAModel> uaModels;
    ArrayList<AdModel> addModels;
    private Random random;
    private HashMap<String, UAModel> usHashMap;
    private static Logger log = Logger.getLogger(NGFXSignupClick.class);
    private INotifier iNotifier;
    String[] lower = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
    String[] upper = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "S", "T", "U", "V", "W", "X", "Y", "Z"};
    String[] number = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
    String[] charset = {"a", "A", "b", "B", "1", "c", "C", "d", "D", "e", "E", "2", "f", "F", "g", "G", "h", "H", "3", "i", "I", "j", "J", "k", "K", "4", "l", "L", "m", "M", "n", "N", "o", "O", "5", "p", "P", "q", "Q", "r", "R", "6", "s", "S", "t", "T", "7", "u", "U", "v", "8", "w", "W", "x", "X", "y", "Y", "9", "z", "Z",};
    ArrayList<String> region;
    ArrayList<String> month;
    ArrayList<String> petNames;
    ArrayList<String> chilhoodFriends;
    ArrayList<String> firstLovers;
    ArrayList<String> motherMaidens;
    ArrayList<String> schoolTeachers;
    HashMap<String, ArrayList<String>> securityA;

    public NetellerSignupClick(INotifier iNotifier, SModel sModel) {
        this.sModel = sModel;
        this.iNotifier = iNotifier;
    }

    public NetellerSignupClick(SModel iModel) {
        this.sModel = iModel;
    }

    public Random getRandom() {
        if (random == null) {
            random = new Random();
        }
        return random;
    }

    public void setRandom(Random random) {
        this.random = random;
    }

    @Override
    public void run() {
        try {
            String uri = "http://" + IConstant.HOSTNAME + "/index.php?r=netellerAccount/getAccounts&username="
                    + sModel.getUsername() + "&password=" + sModel.getPassword() + "&working=1";
            String response = HttpHelper.post(new URL(uri), "");
            Document document = DocumentHelper.parseText(response);
            String errorCode = document.valueOf("Response/errorcode");
            if (!errorCode.equalsIgnoreCase("000")) {
                List<Node> list = document.selectNodes("/Response/accounts/account");
                for (Node node : list) {
                    iNotifier.notify("Robot start working for serial no:" + node.valueOf("serial"));
                    doPost(node);
                    iNotifier.notify("Robot end working for serial no:" + node.valueOf("serial"));
                    break;
                }
            } else {
                String msg = document.valueOf("Response/message");
                iNotifier.notify("Signup:Run:: stopped for error: " + msg);
            }
        } catch (Throwable ex) {
            iNotifier.notify("Signup:Run:: stopped for error: " + ex.getMessage());
            log.error("Signup:Run:: stopped causes " + ex);
        }
    }

    private void doPost(Node node) {
        WebDriver driver = null;
        try {
            String regionv = node.valueOf("region") + " zila";
            if (!this.getRegion().contains(node.valueOf("region").toUpperCase().trim())) {
                iNotifier.notify("Signup:: Region is not valid.");
                Util.wait(3);
                return;
            }

            String monthv = node.valueOf("month");
            if (!this.getMonth().contains(node.valueOf("month").toUpperCase().trim())) {
                iNotifier.notify("Signup:: Month is not valid.");
                Util.wait(3);
                return;
            }

            HashMap<String, String> securityQ = new HashMap<String, String>();
            securityQ.put("PetNames", "First pet's name?");
            securityQ.put("ChilhoodFriends", "Name of best childhood friend?");
            securityQ.put("FirstLovers", "Name of first love?");
            securityQ.put("SchoolTeachers", "Favorite school teacher?");
            securityQ.put("MotherMaidens", "Mother's maiden name?");

            driver = Util.createDriver(sModel,new UAModel());
            if (driver == null) {
                iNotifier.notify("Signup:: unable to init driver. driver is null");
                log.debug("Signup:doPost:: driver is null. Unable to init driver");
                throw new Exception("Signup:doPost:: driver is null. Unable to init driver");
            }
            String link = node.valueOf("link");
            driver.get(link);

            Util.sendKeysById(driver, "currencyCode", "United States Dollar");
            Util.wait(1);

            WebElement eleUName = driver.findElement(By.id("emailAddress"));
            String username = eleUName.getAttribute("value");

            Util.byButton(driver, "button", "type", "submit");
            Util.wait(2);

            Util.byButton(driver, "button", "type", "submit");
            Util.wait(2);

            Util.sendKeysById(driver, "firstName", node.valueOf("first_name"));
            Util.sendKeysById(driver, "lastName", node.valueOf("last_name"));
            this.setAddress(driver, node.valueOf("street"));
            Util.sendKeysById(driver, "city", node.valueOf("city"));

            Util.sendKeysById(driver, "prov", regionv);
            Util.sendKeysById(driver, "postcode", node.valueOf("postcode"));

            Util.byClickName(driver, "primaryPhoneType", "value", "mobile");
            Util.sendKeysById(driver, "primaryPhone", node.valueOf("phone"));
            Util.sendKeysById(driver, "gender", node.valueOf("sex"));
            Util.sendKeysById(driver, "dob_day", node.valueOf("day"));
            Util.sendKeysById(driver, "dob_month", monthv);
            Util.sendKeysById(driver, "dob_year", node.valueOf("year"));

            String password = getPassword();
            System.out.println("password:::" + password);
            Util.sendKeysById(driver, "password", password);
            Util.sendKeysById(driver, "passwordConfirm", password);

            int index = this.getRandom().nextInt(securityQ.size() - 1);
            String key = (String) securityQ.keySet().toArray()[index];
            String question1 = securityQ.get(key);
            securityQ.remove(key);
            Util.sendKeysById(driver, "question1", question1);

            String answer1 = this.getSecurityA().get(key).get(this.getRandom().nextInt(this.getSecurityA().get(key).size() - 1));
            Util.sendKeysById(driver, "answer1", answer1);


            index = this.getRandom().nextInt(securityQ.size() - 1);
            key = (String) securityQ.keySet().toArray()[index];
            String question2 = securityQ.get(key);
            securityQ.remove(key);
            Util.sendKeysById(driver, "question2", question2);

            String answer2 = this.getSecurityA().get(key).get(this.getRandom().nextInt(this.getSecurityA().get(key).size() - 1));
            Util.sendKeysById(driver, "answer2", answer2);

            index = this.getRandom().nextInt(securityQ.size() - 1);
            key = (String) securityQ.keySet().toArray()[index];
            String question3 = securityQ.get(key);
            securityQ.remove(key);
            Util.sendKeysById(driver, "question3", question3);

            String answer3 = this.getSecurityA().get(key).get(this.getRandom().nextInt(this.getSecurityA().get(key).size() - 1));
            Util.sendKeysById(driver, "answer3", answer3);

            Util.byButton(driver, "button", "type", "submit");
            Util.wait(3);

            String mDriver = driver.getWindowHandle(); // save the current window handle.
            WebDriver popup = driver.switchTo().frame(0);
            popup.findElement(By.id("continue_button")).click();
            driver = driver.switchTo().window(mDriver);

            Util.wait(3);
            eleUName = driver.findElement(By.id("accountId"));
            String accountId = eleUName.getText();

            eleUName = driver.findElement(By.id("secureId"));
            String secureId = eleUName.getText();

            Util.sendKeysById(driver, "targetLanding", "View account summary");

            Util.byButton(driver, "confirmId");
            Util.wait(3);

            System.out.println("Username:" + username);
            System.out.println("Passwrod:" + password);
            System.out.println("accountId:" + accountId);
            System.out.println("secureId:" + secureId);

            boolean isOk = true;
            int working = 1;
            try {
                mDriver = driver.getWindowHandle(); // save the current window handle.
                WebDriver ePopup = driver.switchTo().frame(0);
                if (ePopup != null) {
                    isOk = false;
                    working = 3;
                }
            } catch (Throwable tx) {
                tx.printStackTrace();
            }
            driver = driver.switchTo().window(mDriver);

            if (isOk) {
                if (sModel.isLogout()) {
                    Util.byClickTag(driver, "logout");
                }
                working = 2;
            }

            /* Update information */
            try {
                StringBuilder request = new StringBuilder();
                request.append("<Request>");
                request.append("<username>").append(sModel.getUsername()).append("</username>");
                request.append("<password>").append(sModel.getPassword()).append("</password>");
                request.append("<id>").append(node.valueOf("id")).append("</id>");
                request.append("<neteller_username>").append(username).append("</neteller_username>");
                request.append("<neteller_password>").append(password).append("</neteller_password>");
                request.append("<account_no>").append(accountId).append("</account_no>");
                request.append("<security_no>").append(secureId).append("</security_no>");
                request.append("<security_question1>").append(question1).append("</security_question1>");
                request.append("<security_question2>").append(question2).append("</security_question2>");
                request.append("<security_question3>").append(question3).append("</security_question3>");
                request.append("<security_answer1>").append(answer1).append("</security_answer1>");
                request.append("<security_answer2>").append(answer2).append("</security_answer2>");
                request.append("<security_answer3>").append(answer3).append("</security_answer3>");
                request.append("<proxy>").append(sModel.getProxy()).append("</proxy>");
                request.append("<working>").append(working).append("</working>");
                request.append("</Request>");

                String req = URLEncoder.encode(request.toString(), "UTF-8");
                String uri = "http://" + IConstant.HOSTNAME + "/index.php?r=netellerAccount/updateAccInfo";
                String param = "request=" + req;
                String response = HttpHelper.post(new URL(uri), param);

                Document document = DocumentHelper.parseText(response);
                String errorCode = document.valueOf("Response/errorcode");
                String msg = document.valueOf("Response/message");
                log.debug("updateWorking:: update " + msg);

            } catch (Throwable ex) {
                iNotifier.notify("Signup: Error on date save: " + ex.getMessage());
                log.error("Signup:doPost:: Error on data save " + ex);
            }
        } catch (Throwable ex) {
            iNotifier.notify("Signup: Stopped for error: " + ex.getMessage());
            log.error("Signup:doPost:: Stopped causes..." + ex);
            ex.printStackTrace();
        } finally {
            if (driver != null) {
                //driver.close();
            }
        }
    }

    private void setAddress(WebDriver driver, String input) throws Exception {
        StringBuffer address = new StringBuffer();
        StringBuffer line = new StringBuffer();
        address.append(input.toString());
        if (35 < address.toString().length()) {
            this.getAddress(address, line);
            Util.sendKeysById(driver, "address1", line.toString());

            if (35 < address.toString().length()) {
                Util.wait(1);
                Util.byClickTag(driver, "span", "link", "hidden-address2");
                this.getAddress(address, line);
                Util.sendKeysById(driver, "address2", line.toString());
            } else {
                if (!address.toString().isEmpty()) {
                    Util.wait(1);
                    Util.byClickTag(driver, "span", "link", "hidden-address2");
                    Util.sendKeysById(driver, "address2", address.toString());
                    address.setLength(0);
                }
            }

            if (35 < address.toString().length()) {
                Util.wait(1);
                Util.byClickTag(driver, "span", "link", "hidden-address3");
                this.getAddress(address, line);
                Util.sendKeysById(driver, "address3", line.toString());
            } else {
                if (!address.toString().isEmpty()) {
                    Util.wait(1);
                    Util.byClickTag(driver, "span", "link", "hidden-address3");
                    Util.sendKeysById(driver, "address3", address.toString());
                }
            }
        } else {
            Util.sendKeysById(driver, "address1", input);
        }
    }

    public void getAddress(StringBuffer address, StringBuffer line) {
        String output = address.toString();
        line.setLength(0);
        address.setLength(0);

        if (Character.isWhitespace(output.charAt(35))) {
            line.append(output.substring(0, 35).trim());
            address.append(output.substring(35).trim());
        } else {
            line.append(output.substring(0, output.lastIndexOf(" ", 35)).trim());
            address.append(output.substring(output.lastIndexOf(" ", 35)).trim());
        }
    }

    private String getPassword() {
        int lRan = this.getRandom().nextInt(3);
        int uRan = this.getRandom().nextInt(3);
        int nRan = this.getRandom().nextInt(3);

        String password = "";
        for (int j = 0; j <= lRan; j++) {
            password += lower[this.getRandom().nextInt(lower.length - 1)];
        }

        for (int j = 0; j <= uRan; j++) {
            password += upper[this.getRandom().nextInt(upper.length - 1)];
        }

        for (int j = 1; j <= 7; j++) {
            password += charset[this.getRandom().nextInt(charset.length - 1)];
        }

        for (int j = 0; j <= nRan; j++) {
            password += number[this.getRandom().nextInt(number.length - 1)];
        }
        if (password.isEmpty()) {
            password = "A123456Xymn";
        }
        return password;
    }

    public static void main(String s[]) {
        SModel sModel = new SModel();
        sModel.setDriver("FF");
        sModel.setUsername("mithun");
        sModel.setPassword("mithun");
        sModel.setWebMail(false);
        NetellerSignupClick click = new NetellerSignupClick(sModel);

        try {
            String uri = "http://" + IConstant.HOSTNAME + "/index.php?r=netellerAccount/getAccounts&username="
                    + sModel.getUsername() + "&password=" + sModel.getPassword() + "&working=1";
            String response = HttpHelper.post(new URL(uri), "");
            Document document = DocumentHelper.parseText(response);
            String errorCode = document.valueOf("Response/errorcode");
            if (!errorCode.equalsIgnoreCase("000")) {
                List<Node> list = document.selectNodes("/Response/accounts/account");
                int i = 0;
                for (Node node : list) {

                    click.doPost(node);
                    break;
                }
            } else {
                String msg = document.valueOf("Response/message");
            }
        } catch (Throwable ex) {
            log.error("Signup:Run:: stopped causes " + ex);
            ex.printStackTrace();
        }
        //click.doIT();

    }

    private void doIT() {
        SModel sModel = new SModel();
        sModel.setDriver("FF");
        sModel.setLink("http://nigeria-forex.com/forum.php?referrerid=27246");
        sModel.setUseFWlink("0");
        sModel.setUsername("mithun");
        sModel.setPassword("mithun");
        NGFXSignupClick click = new NGFXSignupClick(sModel);
        UAModel model = new UAModel();
        model.setEmail("skyroproject8@gmail.com");
        model.setEmailPassword("mn142536");
        model.setUsername("prantoor");
        model.setPassword("pass123");
        model.setId("22");
        MailRunner mailRunner = new MailRunner(iNotifier, sModel, model);
        mailRunner.checkNGFXEmail(null);
    }

    public boolean readFile(String filename, ArrayList<String> out) {
        BufferedReader br = null;
        try {
            String sCurrentLine;
            br = new BufferedReader(new FileReader(filename));
            while ((sCurrentLine = br.readLine()) != null) {
                out.add(sCurrentLine.trim());
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return false;
    }

    public ArrayList<String> getPetNames() {
        if (petNames == null) {
            petNames = new ArrayList<String>();
            try {
                this.readFile("C:\\irobot\\security_question\\pet_name.txt", petNames);
            } catch (Throwable tx) {
                tx.printStackTrace();
            }
        }
        return petNames;
    }

    public void setPetNames(ArrayList<String> petNames) {
        this.petNames = petNames;
    }

    public ArrayList<String> getChilhoodFriends() {
        if (chilhoodFriends == null) {
            chilhoodFriends = new ArrayList<String>();
            this.readFile("C:\\irobot\\security_question\\chilhood_friend.txt", chilhoodFriends);
        }
        return chilhoodFriends;
    }

    public void setChilhoodFriends(ArrayList<String> chilhoodFriends) {
        this.chilhoodFriends = chilhoodFriends;
    }

    public ArrayList<String> getFirstLovers() {
        if (firstLovers == null) {
            firstLovers = new ArrayList<String>();
            this.readFile("C:\\irobot\\security_question\\first_lover.txt", firstLovers);
        }
        return firstLovers;
    }

    public void setFirstLovers(ArrayList<String> firstLovers) {
        this.firstLovers = firstLovers;
    }

    public ArrayList<String> getMotherMaidens() {
        if (motherMaidens == null) {
            motherMaidens = new ArrayList<String>();
            this.readFile("C:\\irobot\\security_question\\mother_maiden.txt", motherMaidens);
        }
        return motherMaidens;
    }

    public void setMotherMaidens(ArrayList<String> motherMaidens) {
        this.motherMaidens = motherMaidens;
    }

    public ArrayList<String> getSchoolTeachers() {
        if (schoolTeachers == null) {
            schoolTeachers = new ArrayList<String>();
            this.readFile("C:\\irobot\\security_question\\school_teacher.txt", schoolTeachers);
        }
        return schoolTeachers;
    }

    public void setSchoolTeachers(ArrayList<String> schoolTeachers) {
        this.schoolTeachers = schoolTeachers;
    }

    public ArrayList<String> getRegion() {
        if (region == null) {
            region = new ArrayList<String>();
            region.add("BANDARBAN");
            region.add("BARGUNA");
            region.add("BARISAL");
            region.add("BHOLA");
            region.add("BOGRA");
            region.add("BRAHMANBARIA");
            region.add("CHANDPUR");
            region.add("CHAPAINABABGANJ");
            region.add("CHITTAGONG");
            region.add("COMILLA");
            region.add("COX'S BAZAR");
            region.add("DHAKA");
            region.add("DINAJPUR");
            region.add("FARIDPUR");
            region.add("FENI");
            region.add("GAIBANDHA");
            region.add("GAZIPUR");
            region.add("GOPALGANJ");
            region.add("HABIGANJ");
            region.add("JAMALPUR");
            region.add("JESSORE");
            region.add("JHENAIDAH");
            region.add("JOYPURHAT");
            region.add("KHAGRACHHARI");
            region.add("KHULNA");
            region.add("KISHOREGONJ");
            region.add("KURIGRAM");
            region.add("KUSHTIA");
            region.add("LAKSHMIPUR");
            region.add("LALMONIRHAT");
            region.add("MADARIPUR");
            region.add("MAGURA");
            region.add("MANIKGANJ");
            region.add("MAULVIBAZAR");
            region.add("MEHERPUR");
            region.add("MUNSHIGANJ");
            region.add("MYMENSINGH");
            region.add("NAOGAON");
            region.add("NARAIL");
            region.add("NARAYANGANJ");
            region.add("NARSINGDI");
            region.add("NATORE");
            region.add("NETRAKONA");
            region.add("NILPHAMARI");
            region.add("NOAKHALI");
            region.add("PABNA");
            region.add("PANCHAGARH");
            region.add("PATUAKHALI");
            region.add("PIROJPUR");
            region.add("RAJBARI");
            region.add("RAJSHAHI");
            region.add("RANGAMATI");
            region.add("RANGPUR");
            region.add("SATKHIRA");
            region.add("SHARIATPUR");
            region.add("SHERPUR");
            region.add("SIRAJGANJ");
            region.add("SUNAMGANJ");
            region.add("SYLHET");
            region.add("TANGAIL");
            region.add("THAKURGAON");
            region.add("CHUADANGA");
        }
        return region;
    }

    public void setRegion(ArrayList<String> region) {
        this.region = region;
    }

    public ArrayList<String> getMonth() {
        if (month == null) {
            month = new ArrayList<String>();
            month.add("JAN");
            month.add("FEB");
            month.add("MAR");
            month.add("APR");
            month.add("MAY");
            month.add("JUN");
            month.add("JUL");
            month.add("AUG");
            month.add("SEP");
            month.add("OCT");
            month.add("NOV");
            month.add("DEC");
        }
        return month;
    }

    public void setMonth(ArrayList<String> month) {
        this.month = month;
    }

    public HashMap<String, ArrayList<String>> getSecurityA() {
        if (securityA == null) {
            securityA = new HashMap<String, ArrayList<String>>();
            securityA.put("PetNames", this.getPetNames());
            securityA.put("ChilhoodFriends", this.getChilhoodFriends());
            securityA.put("FirstLovers", this.getFirstLovers());
            securityA.put("SchoolTeachers", this.getSchoolTeachers());
            securityA.put("MotherMaidens", this.getMotherMaidens());
        }
        return securityA;
    }

    public void setSecurityA(HashMap<String, ArrayList<String>> securityA) {
        this.securityA = securityA;
    }
}